package com.alibaba.cola.statemachine;

import java.util.List;

/**
 * StateMachine
 *
 * @param <S> the type of state
 * @param <E> the type of event
 * @param <C> the user defined context
 * @author Frank Zhang
 * @date 2020-02-07 2:13 PM
 * <p>
 * 状态机
 */
public interface StateMachine<S, E, C> extends Visitable {

    /**
     * Verify if an event {@code E} can be fired from current state {@code S}
     * 校验sourceStateId对应的状态是否可以触发事件event
     *
     * @param sourceStateId 原状态id
     * @param event         事件
     * @return 是否通过
     */
    boolean verify(S sourceStateId, E event);

    /**
     * Send an event {@code E} to the state machine.
     * 发送一个事件给状态机
     *
     * @param sourceState the source state 原状态
     * @param event       the event to send 发送的事件
     * @param ctx         the user defined context 用户自定义的上下文
     * @return the target state 目标状态
     */
    S fireEvent(S sourceState, E event, C ctx);

    /**
     * 发送一个并行事件给状态机
     *
     * @param sourceState the source state 原状态
     * @param event       the event to send 发送的事件
     * @param ctx         the user defined context 用户自定义的上下文
     * @return the target states 目标状态列表
     */
    List<S> fireParallelEvent(S sourceState, E event, C ctx);

    /**
     * MachineId is the identifier for a State Machine
     * 获取状态机id
     *
     * @return 状态机id，唯一标识
     */
    String getMachineId();

    /**
     * Use visitor pattern to display the structure of the state machine
     * 使用访问者模式来显示状态机的结构
     */
    void showStateMachine();

    /**
     * Generate PlantUML code to display the structure of the state machine
     * 生成PlantUML代码来显示状态机的结构
     *
     * @return PlantUML代码
     */
    String generatePlantUML();
}
